package net.lanelife.casino.caipiao.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Index;
import javax.persistence.Table;

import net.lanelife.casino.common.entity.annotation.Checked;
import net.lanelife.casino.common.entity.support.CheckableEntity;
import net.lanelife.casino.common.utils.StringUtils;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Type;
import org.joda.time.DateTime;

/**
 * 用户
 * 
 * @author Lane
 * 
 */
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "TB_USER", indexes = { 
	@Index(name = "IDX_FLOOR", columnList = "FLOOR"),
	@Index(name = "IDX_PATH", columnList = "PATH"),
	@Index(name = "IDX_PARENT_ID", columnList = "PARENT_ID"),
	@Index(name = "IDX_PARENT_NAME", columnList = "PARENT_NAME"),
})
public class User extends CheckableEntity<Integer> {

	private static final long serialVersionUID = 3589877365682748474L;

	/**
	 * 用户帐号
	 */
	@Checked
	@Column(name = "USER_NAME", length = 16, unique = true, nullable = false)
	private String userName;

	/**
	 * 昵称
	 */
	@Column(name = "NICK_NAME", length = 12, nullable = false)
	private String nickName = "";

	/**
	 * 帐号类型
	 */
	@Checked
	@Enumerated(EnumType.ORDINAL)
	@Column(name = "ACCOUNT_TYPE", nullable = false)
	private AccountType accountType;

	/**
	 * 上级ID
	 */
	@Checked
	@Column(name = "PARENT_ID")
	private Integer parentId;

	/**
	 * 上级帐号
	 */
	@Checked
	@Column(name = "PARENT_NAME", length = 16)
	private String parentName;

	/**
	 * 层级
	 */
	@Checked
	@Column(name = "FLOOR", nullable = false)
	private Integer floor;

	/**
	 * 路径
	 */
	@Checked
	@Column(name = "PATH", length = 200)
	private String path;

	/**
	 * 返点
	 */
	@Checked
	@Column(name = "REBATE_POINT", nullable = false)
	private Double rebatePoint;

	/**
	 * 分层ID
	 */
	@Checked
	@Column(name = "LAYER_ID", nullable = false)
	private Integer layerId;
	
	/**
	 * QQ号码
	 */
	@Column(name = "QQ", length = 15, nullable = false)
	private String qq = "";

	/**
	 * 邮箱
	 */
	@Column(name = "EMAIL", length = 40, nullable = false)
	private String email = "";

	/**
	 * 手机号码
	 */
	@Column(name = "MOBILE", length = 20, nullable = false)
	private String mobile = "";

	/**
	 * 账户余额
	 */
	@Checked
	@Column(name = "BALANCE_ACCOUNT", nullable = false)
	private Double accountBalance = 0D;

	/**
	 * 冻结金额
	 */
	@Checked
	@Column(name = "BALANCE_FROZEN", nullable = false)
	private Double frozenBalance = 0D;

	/**
	 * AG余额
	 */
	@Checked
	@Column(name = "BALANCE_AG", nullable = false)
	private Double agBalance = 0D;

	/**
	 * BB余额
	 */
	@Checked
	@Column(name = "BALANCE_BB", nullable = false)
	private Double bbBalance = 0D;

	/**
	 * 投注总额
	 */
	@Checked
	@Column(name = "BET_TOTAL", nullable = false)
	private Double betTotal = 0D;

	/**
	 * 最大投注金额
	 */
	@Checked
	@Column(name = "BET_MAX", nullable = false)
	private Double betMax = 0D;

	/**
	 * 投注次数
	 */
	@Checked
	@Column(name = "BET_TIMES", nullable = false)
	private Long betTimes = 0L;

	/**
	 * 中奖总额
	 */
	@Checked
	@Column(name = "WIN_TOTAL", nullable = false)
	private Double winTotal = 0D;

	/**
	 * 最大中奖金额
	 */
	@Checked
	@Column(name = "WIN_MAX", nullable = false)
	private Double winMax = 0D;

	/**
	 * 中奖次数
	 */
	@Checked
	@Column(name = "WIN_TIMES", nullable = false)
	private Long winTimes = 0L;

	/**
	 * 充值总额
	 */
	@Checked
	@Column(name = "RECHARGE_TOTAL", nullable = false)
	private Double rechargeTotal = 0D;

	/**
	 * 最大充值金额
	 */
	@Checked
	@Column(name = "RECHARGE_MAX", nullable = false)
	private Double rechargeMax = 0D;

	/**
	 * 充值次数
	 */
	@Checked
	@Column(name = "RECHARGE_TIMES", nullable = false)
	private Long rechargeTimes = 0L;

	/**
	 * 提款总额
	 */
	@Checked
	@Column(name = "WITHDRAW_TOTAL", nullable = false)
	private Double withdrawTotal = 0D;

	/**
	 * 最大提款金额
	 */
	@Checked
	@Column(name = "WITHDRAW_MAX", nullable = false)
	private Double withdrawMax = 0D;

	/**
	 * 提款次数
	 */
	@Checked
	@Column(name = "WITHDRAW_TIMES", nullable = false)
	private Long withdrawTimes = 0L;

	/**
	 * 转入总额
	 */
	@Checked
	@Column(name = "TRANSFER_IN_TOTAL", nullable = false)
	private Double transferInTotal = 0D;

	/**
	 * 最大转入金额
	 */
	@Checked
	@Column(name = "TRANSFER_IN_MAX", nullable = false)
	private Double transferInMax = 0D;

	/**
	 * 转入次数
	 */
	@Checked
	@Column(name = "TRANSFER_IN_TIMES", nullable = false)
	private Long transferInTimes = 0L;

	/**
	 * 转出总额
	 */
	@Checked
	@Column(name = "TRANSFER_OUT_TOTAL", nullable = false)
	private Double transferOutTotal = 0D;

	/**
	 * 最大转出金额
	 */
	@Checked
	@Column(name = "TRANSFER_OUT_MAX", nullable = false)
	private Double transferOutMax = 0D;

	/**
	 * 转出次数
	 */
	@Checked
	@Column(name = "TRANSFER_OUT_TIMES", nullable = false)
	private Long transferOutTimes = 0L;

	/**
	 * 登录密码
	 */
	@Checked
	@Column(name = "PWD_LOGIN", length = 32, nullable = false)
	private String loginPassword;

	/**
	 * 资金密码
	 */
	@Checked
	@Column(name = "PWD_FUNDS", length = 32)
	private String fundsPassword;

	/**
	 * 密码问题
	 */
	@Checked
	@Column(name = "PWD_QUESION", length = 50)
	private String passwordQuesion;

	/**
	 * 密码答案
	 */
	@Checked
	@Column(name = "PWD_ANSWER", length = 32)
	private String passwordAnswer;

	/**
	 * 盐
	 */
	@Checked
	@Column(name = "PWD_SALT", length = 6, nullable = false)
	private String passwordSalt;

	@Checked
	@Enumerated(EnumType.ORDINAL)
	@Column(name = "ONLINE_STATUS", nullable = false)
	private OnlineStatus onlineStatus = OnlineStatus.OFFLINE;
	/**
	 * 账户锁定状态
	 */
	@Checked
	@Column(name = "ACCOUNT_LOCKED", nullable = false)
	private Boolean accountLocked = Boolean.FALSE;

	/**
	 * 登录锁定状态
	 */
	@Checked
	@Column(name = "LOGIN_LOCKED", nullable = false)
	private Boolean loginLocked = Boolean.FALSE;

	/**
	 * 银行卡锁定状态
	 */
	@Checked
	@Column(name = "BANK_CARD_LOCKED", nullable = false)
	private Boolean bankCardLocked = Boolean.FALSE;

	/**
	 * 分层锁定状态
	 */
	@Checked
	@Column(name = "LAYER_LOCKED", nullable = false)
	private Boolean layerLocked = Boolean.FALSE;

	/**
	 * 登录密码最后修改时间
	 */
	@Column(name = "LOGIN_PWD_LAST_MODIFIED_DATE")
	@Type(type = "net.lanelife.casino.common.entity.usertype.PersistentDateTimeAsMillisLong")
	private DateTime loginPasswordLastModifiedDate;

	/**
	 * 资金密码最后修改时间
	 */
	@Column(name = "FUNDS_PWD_LAST_MODIFIED_DATE")
	@Type(type = "net.lanelife.casino.common.entity.usertype.PersistentDateTimeAsMillisLong")
	private DateTime fundsPasswordLastModifiedDate;

	/**
	 * 最后登录时间
	 */
	@Column(name = "LAST_LOGIN_TIME")
	@Type(type = "net.lanelife.casino.common.entity.usertype.PersistentDateTimeAsMillisLong")
	private DateTime lastLoginTime;

	/**
	 * 最后提款时间
	 */
	@Column(name = "LAST_WITHDRAW_TIME")
	@Type(type = "net.lanelife.casino.common.entity.usertype.PersistentDateTimeAsMillisLong")
	private DateTime lastWithdrawTime;

	/**
	 * 注册来源
	 */
	@Enumerated(EnumType.ORDINAL)
	@Column(name = "REGISTER_SOURCE", length = 10, nullable = false)
	private RegisterSource registerSource;

	/**
	 * 最后登录地址
	 */
	@Column(name = "LAST_LOGIN_ADDR", nullable = false)
	private String lastLoginAddress = "";

	/**
	 * 登录失败次数
	 */
	@Checked
	@Column(name = "LOGIN_FAILURE_TIMES", nullable = false)
	private Integer loginFailureTimes = 0;
	
	@Checked
	@Column(name = "QUOTA", nullable = false)
	private String quota;
	
	@Checked
	@Column(name = "EXPEND_QUOTA", nullable = false)
	private Integer expendQuota = 0;

	/**
	 * 帐号类型
	 */
	public static enum AccountType {
		/**
		 * 管理员
		 */
		MANAGER,
		/**
		 * 代理
		 */
		AGENT,
		/**
		 * 会员
		 */
		MEMBER
	}

	/**
	 * 注册来源
	 */
	public static enum RegisterSource {
		/**
		 * 手工开户
		 */
		MANUAL,
		/**
		 * 注册链接
		 */
		CODE
	}
	
	public static enum OnlineStatus {
		ONLINE, OFFLINE
	}
	
	public static class Quota {
		private Double beginRebatePoint;
		private Double endRebatePoint;
		private Long quota;
		public Quota(Double beginRebatePoint, Double endRebatePoint, Long quota) {
			super();
			this.beginRebatePoint = beginRebatePoint;
			this.endRebatePoint = endRebatePoint;
			this.quota = quota;
		}
		public Double getBeginRebatePoint() {
			return beginRebatePoint;
		}
		public void setBeginRebatePoint(Double beginRebatePoint) {
			this.beginRebatePoint = beginRebatePoint;
		}
		public Double getEndRebatePoint() {
			return endRebatePoint;
		}
		public void setEndRebatePoint(Double endRebatePoint) {
			this.endRebatePoint = endRebatePoint;
		}
		public Long getQuota() {
			return quota;
		}
		public void setQuota(Long quota) {
			this.quota = quota;
		}
	}

	public User() {

	}

	public User(Integer id, String userName) {
		this.setId(id);
		this.setUserName(userName);
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getNickName() {
		return nickName;
	}

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}

	public AccountType getAccountType() {
		return accountType;
	}

	public void setAccountType(AccountType accountType) {
		this.accountType = accountType;
	}

	public Integer getParentId() {
		return parentId;
	}

	public void setParentId(Integer parentId) {
		this.parentId = parentId;
	}

	public String getParentName() {
		return parentName;
	}

	public void setParentName(String parentName) {
		this.parentName = parentName;
	}

	public Integer getFloor() {
		return floor;
	}

	public void setFloor(Integer floor) {
		this.floor = floor;
	}

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public Double getRebatePoint() {
		return rebatePoint;
	}

	public void setRebatePoint(Double rebatePoint) {
		this.rebatePoint = rebatePoint;
	}
	
	public Integer getLayerId() {
		return layerId;
	}

	public void setLayerId(Integer layerId) {
		this.layerId = layerId;
	}

	public String getQq() {
		return qq;
	}

	public void setQq(String qq) {
		this.qq = qq;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public Double getAccountBalance() {
		return accountBalance;
	}

	public void setAccountBalance(Double accountBalance) {
		this.accountBalance = accountBalance;
	}

	public Double getFrozenBalance() {
		return frozenBalance;
	}

	public void setFrozenBalance(Double frozenBalance) {
		this.frozenBalance = frozenBalance;
	}

	public Double getAgBalance() {
		return agBalance;
	}

	public void setAgBalance(Double agBalance) {
		this.agBalance = agBalance;
	}

	public Double getBbBalance() {
		return bbBalance;
	}

	public void setBbBalance(Double bbBalance) {
		this.bbBalance = bbBalance;
	}

	public Double getBetTotal() {
		return betTotal;
	}

	public void setBetTotal(Double betTotal) {
		this.betTotal = betTotal;
	}

	public Double getBetMax() {
		return betMax;
	}

	public void setBetMax(Double betMax) {
		this.betMax = betMax;
	}

	public Long getBetTimes() {
		return betTimes;
	}

	public void setBetTimes(Long betTimes) {
		this.betTimes = betTimes;
	}

	public Double getWinTotal() {
		return winTotal;
	}

	public void setWinTotal(Double winTotal) {
		this.winTotal = winTotal;
	}

	public Double getWinMax() {
		return winMax;
	}

	public void setWinMax(Double winMax) {
		this.winMax = winMax;
	}

	public Long getWinTimes() {
		return winTimes;
	}

	public void setWinTimes(Long winTimes) {
		this.winTimes = winTimes;
	}

	public Double getRechargeTotal() {
		return rechargeTotal;
	}

	public void setRechargeTotal(Double rechargeTotal) {
		this.rechargeTotal = rechargeTotal;
	}

	public Double getRechargeMax() {
		return rechargeMax;
	}

	public void setRechargeMax(Double rechargeMax) {
		this.rechargeMax = rechargeMax;
	}

	public Long getRechargeTimes() {
		return rechargeTimes;
	}

	public void setRechargeTimes(Long rechargeTimes) {
		this.rechargeTimes = rechargeTimes;
	}

	public Double getWithdrawTotal() {
		return withdrawTotal;
	}

	public void setWithdrawTotal(Double withdrawTotal) {
		this.withdrawTotal = withdrawTotal;
	}

	public Double getWithdrawMax() {
		return withdrawMax;
	}

	public void setWithdrawMax(Double withdrawMax) {
		this.withdrawMax = withdrawMax;
	}

	public Long getWithdrawTimes() {
		return withdrawTimes;
	}

	public void setWithdrawTimes(Long withdrawTimes) {
		this.withdrawTimes = withdrawTimes;
	}

	public Double getTransferInTotal() {
		return transferInTotal;
	}

	public void setTransferInTotal(Double transferInTotal) {
		this.transferInTotal = transferInTotal;
	}

	public Double getTransferInMax() {
		return transferInMax;
	}

	public void setTransferInMax(Double transferInMax) {
		this.transferInMax = transferInMax;
	}

	public Long getTransferInTimes() {
		return transferInTimes;
	}

	public void setTransferInTimes(Long transferInTimes) {
		this.transferInTimes = transferInTimes;
	}

	public Double getTransferOutTotal() {
		return transferOutTotal;
	}

	public void setTransferOutTotal(Double transferOutTotal) {
		this.transferOutTotal = transferOutTotal;
	}

	public Double getTransferOutMax() {
		return transferOutMax;
	}

	public void setTransferOutMax(Double transferOutMax) {
		this.transferOutMax = transferOutMax;
	}

	public Long getTransferOutTimes() {
		return transferOutTimes;
	}

	public void setTransferOutTimes(Long transferOutTimes) {
		this.transferOutTimes = transferOutTimes;
	}

	public String getLoginPassword() {
		return loginPassword;
	}

	public void setLoginPassword(String loginPassword) {
		this.loginPassword = loginPassword;
	}

	public String getFundsPassword() {
		return fundsPassword;
	}

	public void setFundsPassword(String fundsPassword) {
		this.fundsPassword = fundsPassword;
	}

	public String getPasswordQuesion() {
		return passwordQuesion;
	}

	public void setPasswordQuesion(String passwordQuesion) {
		this.passwordQuesion = passwordQuesion;
	}

	public String getPasswordAnswer() {
		return passwordAnswer;
	}

	public void setPasswordAnswer(String passwordAnswer) {
		this.passwordAnswer = passwordAnswer;
	}

	public String getPasswordSalt() {
		return passwordSalt;
	}

	public void setPasswordSalt(String passwordSalt) {
		this.passwordSalt = passwordSalt;
	}

	public OnlineStatus getOnlineStatus() {
		return onlineStatus;
	}

	public void setOnlineStatus(OnlineStatus onlineStatus) {
		this.onlineStatus = onlineStatus;
	}

	public Boolean getAccountLocked() {
		return accountLocked;
	}

	public void setAccountLocked(Boolean accountLocked) {
		this.accountLocked = accountLocked;
	}

	public Boolean getLoginLocked() {
		return loginLocked;
	}

	public void setLoginLocked(Boolean loginLocked) {
		this.loginLocked = loginLocked;
	}

	public Boolean getBankCardLocked() {
		return bankCardLocked;
	}

	public void setBankCardLocked(Boolean bankCardLocked) {
		this.bankCardLocked = bankCardLocked;
	}

	public Boolean getLayerLocked() {
		return layerLocked;
	}

	public void setLayerLocked(Boolean layerLocked) {
		this.layerLocked = layerLocked;
	}

	public DateTime getLoginPasswordLastModifiedDate() {
		return loginPasswordLastModifiedDate;
	}

	public void setLoginPasswordLastModifiedDate(
			DateTime loginPasswordLastModifiedDate) {
		this.loginPasswordLastModifiedDate = loginPasswordLastModifiedDate;
	}

	public DateTime getFundsPasswordLastModifiedDate() {
		return fundsPasswordLastModifiedDate;
	}

	public void setFundsPasswordLastModifiedDate(
			DateTime fundsPasswordLastModifiedDate) {
		this.fundsPasswordLastModifiedDate = fundsPasswordLastModifiedDate;
	}

	public DateTime getLastLoginTime() {
		return lastLoginTime;
	}

	public void setLastLoginTime(DateTime lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}

	public DateTime getLastWithdrawTime() {
		return lastWithdrawTime;
	}

	public void setLastWithdrawTime(DateTime lastWithdrawTime) {
		this.lastWithdrawTime = lastWithdrawTime;
	}

	public RegisterSource getRegisterSource() {
		return registerSource;
	}

	public void setRegisterSource(RegisterSource registerSource) {
		this.registerSource = registerSource;
	}

	public String getLastLoginAddress() {
		return lastLoginAddress;
	}

	public void setLastLoginAddress(String lastLoginAddress) {
		this.lastLoginAddress = lastLoginAddress;
	}

	public Integer getLoginFailureTimes() {
		return loginFailureTimes;
	}

	public void setLoginFailureTimes(Integer loginFailureTimes) {
		this.loginFailureTimes = loginFailureTimes;
	}
	
	public String getQuota() {
		return quota;
	}

	public void setQuota(String quota) {
		this.quota = quota;
	}

	public Integer getExpendQuota() {
		return expendQuota;
	}

	public void setExpendQuota(Integer expendQuota) {
		this.expendQuota = expendQuota;
	}

	public Boolean hasParent() {
		return StringUtils.isNotBlank(getParentName());
		//return null != getParentName();
	}
	
	public Boolean validateInformation(String regex) {
		if (userName != null && userName.matches(regex)) {
			return Boolean.FALSE;
		}
		if (nickName != null && nickName.matches(regex)) {
			return Boolean.FALSE;
		}
		return Boolean.TRUE;
	}

}
